package com.lintf.bot.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lintf.bot.domain.BotBill;
import com.lintf.bot.domain.BotBillCell;
import com.lintf.bot.domain.BotBillCellUser;
import com.lintf.bot.domain.BotItem;
import com.lintf.bot.domain.constant.Constant;
import com.lintf.bot.domain.dto.BotBillAddDTO;
import com.lintf.bot.domain.dto.BotBillListDTO;
import com.lintf.bot.domain.dto.BotBillUpdateDTO;
import com.lintf.bot.domain.enums.NoticeTypeEnums;
import com.lintf.bot.domain.model.BotBillModel;
import com.lintf.bot.domain.vo.BotBillListOfSimpleVo;
import com.lintf.bot.domain.vo.BotBillListVo;
import com.lintf.bot.mapper.BotBillMapper;
import com.lintf.bot.notice.NoticeUtils;
import com.lintf.bot.service.IBotBillCellService;
import com.lintf.bot.service.IBotBillCellUserService;
import com.lintf.bot.service.IBotBillService;
import com.lintf.bot.service.IBotItemService;
import com.lintf.common.core.domain.entity.SysUser;
import com.lintf.common.utils.SecurityUtils;
import com.lintf.system.service.ISysUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lintf
 * @description 针对表【bot_bill】的数据库操作Service实现
 * @createDate 2024-01-07 00:25:23
 */
@Service
public class BotBillServiceImpl extends ServiceImpl<BotBillMapper, BotBill>
        implements IBotBillService {

    @Autowired
    private IBotBillCellService botBillCellService;
    @Autowired
    private IBotBillCellUserService botBillCellUserService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private IBotItemService botItemService;
    @Autowired
    private NoticeUtils noticeUtils;

    @Override
    public BotBillListVo getById(BotBillListDTO dto) {
        BotBill bill = baseMapper.selectById(dto.getBillId());
        if (bill == null) {
            return null;
        }
        BotBillListVo vo = new BotBillListVo();
        LambdaQueryWrapper<BotBillCellUser> innerUserWrapper;
        LambdaQueryWrapper<BotItem> innerItemWrapper;
        BeanUtils.copyProperties(bill, vo);
        List<BotBillCell> botBillCells = new ArrayList<>();
        BotBillCell cell = botBillCellService.getById(dto.getCellId());
        innerUserWrapper = new LambdaQueryWrapper<>();
        innerUserWrapper.eq(BotBillCellUser::getBotBillCellId, cell.getId());
        List<BotBillCellUser> billCellUsers = botBillCellUserService.list(innerUserWrapper);
        for (BotBillCellUser billCellUser : billCellUsers) {
            billCellUser.setSysUser(sysUserService.selectUserById(billCellUser.getUserId()));
            innerItemWrapper = new LambdaQueryWrapper<>();
            innerItemWrapper.eq(BotItem::getRefId, billCellUser.getId())
                    .orderByDesc(BotItem::getUpdateTime);
            billCellUser.setBotItemList(botItemService.list(innerItemWrapper));
        }
        cell.setBillCellUserList(billCellUsers);
        botBillCells.add(cell);
        vo.setBotBillCells(botBillCells);
        SysUser sysUser = sysUserService.selectUserById(bill.getUserId());
        vo.setAvatar(sysUser.getAvatar());
        vo.setNickName(sysUser.getNickName());
        return vo;
    }

    @Override
    public List<BotBillListOfSimpleVo> list(BotBillListDTO dto) {
        LambdaQueryWrapper<BotBill> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(BotBill::getIsHide, 0).orderByDesc(BotBill::getCreateTime);
        if (dto.isOwnData()) {
            wrapper.eq(BotBill::getCreateBy, SecurityUtils.getUserId());
        }
        if (dto.getGroupId() != null) {
            wrapper.eq(BotBill::getGroupId, dto.getGroupId());
        } else {
            wrapper.eq(BotBill::getGroupId, 0);
        }
        if (StringUtils.isNotEmpty(dto.getSearchValue())) {
            wrapper.like(BotBill::getTitle, dto.getSearchValue());
        }
        if (StringUtils.isNotEmpty(dto.getDateSearchValue())) {
            LocalDateTime startTime = LocalDateTime.parse(dto.getDateSearchValue() + "T00:00:00");
            LocalDateTime endTime = LocalDateTime.parse(dto.getDateSearchValue() + "T23:59:59");
            wrapper.ge(BotBill::getCreateTime, startTime)
                    .le(BotBill::getCreateTime, endTime);
        }
        Page<BotBill> page = new Page<>(dto.getPageNum(), dto.getPageSize());
        List<BotBill> list = baseMapper.selectPage(page, wrapper).getRecords();
        List<BotBillModel> concatList = new ArrayList<>();
        for (BotBill botBill : list) {
            concatList.addAll(baseMapper.selectRefInfo(botBill.getId()));
        }
        Map<Integer, Map<Integer, List<BotBillModel>>> collect = concatList.stream().filter(botBillModel -> botBillModel.getCellId() != null).collect(Collectors.groupingBy(BotBillModel::getId,
                Collectors.groupingBy(BotBillModel::getCellId)));
        List<BotBillListOfSimpleVo> result = new ArrayList<>();
        for (Map.Entry<Integer, Map<Integer, List<BotBillModel>>> entry : collect.entrySet()) {
            BotBillListOfSimpleVo listVo = new BotBillListOfSimpleVo();
            listVo.setId(entry.getKey());
            ArrayList<BotBillListOfSimpleVo.BotBillCellListOfSimple> billCells = new ArrayList<>();
            for (Map.Entry<Integer, List<BotBillModel>> listEntry : entry.getValue().entrySet()) {
                BotBillListOfSimpleVo.BotBillCellListOfSimple cell = new BotBillListOfSimpleVo.BotBillCellListOfSimple();
                cell.setId(listEntry.getKey());
                List<BotBillModel> value = listEntry.getValue();
                List<String> avatar = new ArrayList<>();
                boolean executed = false; // 声明并初始化标志变量
                for (BotBillModel model : value) {
                    if (!executed) { // 检查标志变量是否为false
                        cell.setPlanTitle(model.getPlanTitle())
                                .setStatus(model.getCellStatus())
                                .setStartTime(model.getStartTime())
                                .setEndTime(model.getEndTime());
                        listVo.setUserId(model.getCreateBy())
                                .setTitle(model.getTitle())
                                .setStatus(model.getStatus());
                        executed = true; // 将标志变量设置为true，表示已经执行过这部分逻辑
                    }
                    avatar.add(model.getAvatar());
                }
                cell.setAvatar(avatar);
                billCells.add(cell);
            }
            listVo.setCellListOfSimples(billCells);
            listVo.setAvatar(sysUserService.selectUserById(listVo.getUserId()).getAvatar());
            result.add(listVo);
        }
        return result.stream().sorted(Comparator.comparing(BotBillListOfSimpleVo::getId).reversed()).collect(Collectors.toList());
    }

    /**
     * 添加账单
     *
     * @param dto
     */
    @Override
    @Transactional
    public void add(BotBillAddDTO dto) {
        // 获取当前用户ID和昵称
        Long userId = SecurityUtils.getUserId();
        String nickName = SecurityUtils.getLoginUser().getUser().getNickName();
        // 创建账单对象并复制属性
        BotBill botBill = new BotBill();
        BeanUtils.copyProperties(dto, botBill);
        botBill.setUserId(userId);
//        botBill.setCreateParams();
        // 插入账单信息
        if (baseMapper.insert(botBill) != 0) {
            // 处理清单明细
            List<BotBillCell> list = dto.getBotBillCells();
            list.forEach(item -> {
                item.setBotBillId(botBill.getId());
//                item.setCreateParams();
            });
            // 批量保存清单明细
            if (botBillCellService.saveBatch(list) && StringUtils.equals(dto.getTitle(), Constant.TO_DO_ITEM)) {
                // 处理推送相关逻辑
                List<Map<String, Object>> params = new ArrayList<>();
                List<BotBillCellUser> botBillCellUsers = new ArrayList<>();
                Set<SysUser> pushUserList = new HashSet<>();
                for (BotBillCell cell : list) {
                    pushUserList.addAll(cell.getSelectedUserList());
                    for (SysUser user : cell.getSelectedUserList()) {
                        BotBillCellUser botBillCellUser = new BotBillCellUser();
                        botBillCellUser.setBotBillCellId(cell.getId())
                                .setUserId(user.getUserId());
//                                .setCreateParams();
                        botBillCellUsers.add(botBillCellUser);
                        Map<String, Object> param = new HashMap<>();
                        param.put("refId", cell.getId());
                        param.put("refUserId", user.getUserId());
                        params.add(param);
                    }
                }
                // 批量保存清单明细用户信息
                botBillCellUserService.saveBatch(botBillCellUsers);
                // 发送用户通知
                noticeUtils.personListPush(null, Constant.TO_DO_PROCESSING, NoticeTypeEnums.TO_DO_PROCESSING, Constant.TO_DO_PROCESSING, null, params, dto.getGroupId());
            }
            // 发送系统通知
            String noticeTitle = nickName + "发布了一条" + dto.getTitle();
            noticeUtils.systemPush(botBill.getId(), noticeTitle, NoticeTypeEnums.BILL_PUBLISH, Constant.BILL, nickName + "的" + dto.getTitle(), botBill.getCreateTime(), dto.getGroupId());
        }
    }

    @Override
    public void update(BotBillUpdateDTO dto) {
        BotBill botBill = new BotBill();
        BeanUtils.copyProperties(dto, botBill);
//        botBill.setUpdateParams();
        baseMapper.updateById(botBill);
    }

    @Override
    public void remove(BotBillUpdateDTO dto) {
        BotBill botBill = new BotBill();
        BeanUtils.copyProperties(dto, botBill);
//        botBill.setUpdateParams();
        baseMapper.deleteById(botBill);
    }
}




